feat(sync): handle duplicate skill names across plugins#27
Merged
Conversation
Deploying allagents with
|
| Latest commit: |
a932c0c
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://6f5a4adc.allagents.pages.dev |
| Branch Preview URL: | https://feat-duplicate-skill-naming.allagents.pages.dev |
1f508d1 to
472b42b
Compare
Add getShortId() function that generates a deterministic 6-character hexadecimal hash from a string input using SHA-256. This will be used for local path disambiguation when multiple plugins have skills with the same folder name and plugin name. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add extractOrgFromSource() function that extracts the organization/owner from various GitHub source URL formats. This is used for skill name disambiguation when multiple plugins have skills with the same folder name and plugin name. Supports: - github:org/repo and github:org/repo#branch - gh:org/repo and gh:org/repo#branch - https://github.com/org/repo and full URLs with paths - github.com/org/repo (no protocol) - org/repo shorthand format - Returns null for local paths (caller uses hash fallback) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements three-tier naming resolution for skills with duplicate names:
1. No conflict - use skill folder name as-is
2. Folder name conflicts - qualify with plugin name: {plugin}_{skill}
3. Both conflict - add org/hash prefix: {orgOrUuid}_{plugin}_{skill}
Uses getShortId() for local paths and extractOrgFromSource() for GitHub.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Refactors the sync process to collect all skills from all plugins before
copying, enabling automatic duplicate skill name handling:
- Add SkillCopyOptions and PluginCopyOptions interfaces to transform.ts
- Add collectPluginSkills() to gather skill entries from plugins
- Add getPluginName() to read plugin name from plugin.json or fallback
to directory name
- Modify copySkills() to accept optional skillNameMap for resolved names
- Add collectAllSkills() and buildPluginSkillNameMaps() to sync.ts
- Update syncWorkspace() to use two-pass resolution:
Pass 1: Collect all skills from validated plugins
Pass 2: Copy skills using resolved names from the skill name resolver
When skill folder names conflict:
- Unique plugins qualify with plugin name: {plugin}_{skill}
- Same plugin names add org/hash prefix: {org}_{plugin}_{skill}
Backward compatible: when no conflicts, skills use original folder names.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive integration tests that verify the full sync flow
with duplicate skills across multiple scenarios:
- No conflict: skill names unchanged
- Skill conflict with different plugins: {plugin}_{skill} format
- Skill + plugin conflict with local sources: {hash}_{plugin}_{skill} format
- Mixed conflict levels in single workspace
- State tracking and purging of renamed skills
- Skill content preservation during renaming
- Edge cases (no plugin.json, empty skills dir, etc.)
Tests use the existing test infrastructure with real file system
operations and verify actual sync output.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Explains the automatic naming resolution when multiple plugins define skills with the same folder name. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Plan completed and behavior documented in docs/guides/plugins.mdx Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
472b42b to
3dbef10
Compare
Reduce test count from 110 to ~55: - source-parser: 38 → 6 tests (consolidated assertions) - integration: 25 → 7 tests (removed redundant scenarios) - Removed separate GitHub integration test file Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
{plugin}_{skill}{org}_{plugin}_{skill}(GitHub) or{hash}_{plugin}_{skill}(local)Changes
src/utils/hash.ts- 6-char deterministic hash utility for local path disambiguationsrc/utils/source-parser.ts- Extract org from GitHub source URLssrc/utils/skill-name-resolver.ts- Three-tier naming resolution logicsrc/core/transform.ts- Two-pass skill copying with name resolutionsrc/core/sync.ts- Collect all skills before copying, resolve names globallyTest Plan
🤖 Generated with Claude Code